<?php
// +----------------------------------------------------------------------
// | 应用公共文件
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 
// +----------------------------------------------------------------------


use think\facade\Db;
use think\facade\Log;
use think\facade\Config;
use think\facade\Request;
use think\facade\Cache;
use yt\helper\StringHelper;
error_reporting(0);

function genTree($rows, $parent = 0, $idKey = 'id', $parentKey = 'parent', $childrenKey = 'children')
{
    $rowsEnd = [];
    foreach ($rows as $row) {
        $rowsEnd[$row[$idKey]] = $row;
    }
    foreach ($rowsEnd as $_key => $row) {
        $rowsEnd[$row[$parentKey]][$childrenKey][] = &$rowsEnd[$_key];
    }

    return isset($rowsEnd[$parent][$childrenKey]) ? $rowsEnd[$parent][$childrenKey] : [];
}

//重复提交验证
function setRequestData($key) {
    if (!$key) return false;
    $redis = new Redis(Config::get('cache.stores.redis'));
    $redis->set($key,1);
    $redis->expire($key, 15);
}
function getRequestData($key) {
    if (!$key) return false;
    $redis = new Redis(Config::get('cache.stores.redis'));
    return $redis->get($key);
}
function clearRequestData($key) {
    if (!$key) return false;
    $redis = new Redis(Config::get('cache.stores.redis'));
    $redis->del($key);
}

function getHost() {
    $host = Request::host(true);
    // 如果是非SSL则添加http头
    if (!Request::isSsl()) {
        $host = 'http://' . $host;
    } else {
        $host = 'https://' . $host;
    }
    return $host;
}

function storage_path($dir,$name) {
    return app()->getRootPath() . 'public/uploads/'.$dir.'/'.$name;
}

/**
 * 数字转中文
 */
function numToWord($num) {
    $chiNum = array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
    $chiUni = array('','十', '百', '千', '万', '亿', '十', '百', '千');
    $chiStr = '';
    $num_str = (string)$num;
    $count = strlen($num_str);
    $last_flag = true; //上一个 是否为0
    $zero_flag = true; //是否第一个
    $temp_num = null; //临时数字
    
    $chiStr = '';//拼接结果
    if ($count == 2) {//两位数
        $temp_num = $num_str[0];
        $chiStr = $temp_num == 1 ? $chiUni[1] : $chiNum[$temp_num].$chiUni[1];
        $temp_num = $num_str[1];
        $chiStr .= $temp_num == 0 ? '' : $chiNum[$temp_num]; 
    }else if($count > 2){
        $index = 0;
        for ($i=$count-1; $i >= 0 ; $i--) { 
            $temp_num = $num_str[$i];
            if ($temp_num == 0) {
                if (!$zero_flag && !$last_flag ) {
                    $chiStr = $chiNum[$temp_num]. $chiStr;
                    $last_flag = true;
                }
            }else{
                $chiStr = $chiNum[$temp_num].$chiUni[$index%9] .$chiStr;
                
                $zero_flag = false;
                $last_flag = false;
            }
            $index ++;
        }
    }else{
        $chiStr = $chiNum[$num_str[0]]; 
    }
    return $chiStr;
}
/**
 * 验证身份证号是否正确
 */
function checkIdentityNo($cardid) {

    // 只能是18位
    if( strlen ($cardid)!=18){
        return false;
    }

    // 取出前17位
    $idcard_base = substr($cardid, 0, 17);

    // 取出校验码
    $verifycode = substr($cardid, 17, 1);

    // 加权因子
    $factor = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);

    // 校验码对应值
    $verify_code_arr = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');

    // 根据前17位计算校验码
    $S = 0;
    for ($i=0; $i<17; $i++) {
        $S += substr($idcard_base, $i, 1)*$factor[$i];
    }

    // 取模
    $mod = $S% 11;

    // 比较校验码
    if ($verifycode == $verify_code_arr[$mod]) {
        return true;
    } else {
        return false;
    }
}

//获取字符串写到文件的临时路径
function getTmpPathByContent($content){
    static $tmpFile = null;
    $tmpFile = tmpfile();
    fwrite($tmpFile, $content);
    $tempPemPath = stream_get_meta_data($tmpFile);
    return $tempPemPath['uri'];
}

function makeContentTmpPath($fid, $content, $fileName) {
    $rootPath = public_path ().'uploads/wx/tmp/'.$fid.'_'.$fileName;
    file_put_contents($rootPath, $content);
    return $rootPath;
}

function getPayType($authCode) {
    //微信条码规则：用户付款码条形码规则：18位纯数字，以10、11、12、13、14、15开头
    //支付宝条码规则：付款码将由原来的28开头扩充到25-30开头，长度由原来的16-18位扩充到16-24位
    $type = [
        'wechat' => [10,11,12,13,14,15],
        'alipay' => [25,26,27,28,29,30],
    ];
    $pre = substr($authCode, 0, 2);
    foreach ($type as $k => $rs) {
        if (in_array($pre, $rs)) {
            return $k;
        }
    }
    return 'other';
}

function MakeSign($array, $key)
{
    // 签名步骤一：按字典序排序参数
    ksort($array);

    $string = ToUrlParams($array); 
    // 签名步骤二：在string后加入KEY
    $string = $string . "&key=" . $key;
    // 签名步骤三：MD5加密
    $string = md5($string);
    // 签名步骤四：所有字符转为大写
    $result = strtoupper($string);
    return $result;
}

function ToUrlParams($arr)
{
    $buff = "";
    foreach ($arr as $k => $v) {
        if ($k != "sign" && $v != "" && ! is_array($v)) {
            $buff .= $k . "=" . $v . "&";
        }
    }
    $buff = trim($buff, "&");
    return $buff;
}

function getToken($user_id) {
    $token = md5($user_id.StringHelper::uuid('uniqid'));
    return $token;
}

function timeDiff($time) {
    return intval($time/3600).'时'.intval($time%3600/60).'分';
}

/**
 * 计算两点地理坐标之间的距离
 * @param  Decimal $longitude1 起点经度
 * @param  Decimal $latitude1  起点纬度
 * @param  Decimal $longitude2 终点经度 
 * @param  Decimal $latitude2  终点纬度
 * @param  Int     $unit       单位 1:米 2:公里
 * @param  Int     $decimal    精度 保留小数位数
 * @return Decimal
*/
function getDistance($latitude1, $longitude1, $latitude2, $longitude2,  $unit=2, $decimal=2){
 
    $EARTH_RADIUS = 6370.996; // 地球半径系数
    $PI = 3.1415926;
 
    $radLat1 = $latitude1 * $PI / 180.0;
    $radLat2 = $latitude2 * $PI / 180.0;
 
    $radLng1 = $longitude1 * $PI / 180.0;
    $radLng2 = $longitude2 * $PI /180.0;
 
    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;
 
    $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
    $distance = $distance * $EARTH_RADIUS * 1000;
 
    if($unit==2){
        $distance = $distance / 1000;
    }
 
    return round($distance, $decimal);
 
}

// //根据两个地方坐标计算距离
// function getDistance($lat1, $lng1, $lat2, $lng2) 
// { 
//     $earthRadius = 6367000; //地球半径
//     $lat1 = ($lat1 * pi()) / 180;
//     $lng1 = ($lng1 * pi()) / 180;

//     $lat2 = ($lat2 * pi()) / 180;
//     $lng2 = ($lng2 * pi()) / 180;
//     $calcLongitude = $lng2 - $lng1;
//     $calcLatitude = $lat2 - $lat1;
//     $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
//     $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
//     $calculatedDistance = $earthRadius * $stepTwo;
//     return round($calculatedDistance);
// } 
/**
 * 随机字符
 * @param int $length 长度
 * @param string $type 类型
 * @param int $convert 转换大小写 1大写 0小写
 * @return string
 */
function random($length=10, $type='letter', $convert=0)
{
    $config = array(
        'number'=>'1234567890',
        'letter'=>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        'string'=>'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789',
        'all'=>'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
    );

    if(!isset($config[$type])) $type = 'letter';
    $string = $config[$type];

    $code = '';
    $strlen = strlen($string) -1;
    for($i = 0; $i < $length; $i++){
        $code .= $string[mt_rand(0, $strlen)];
    }
    if(!empty($convert)){
        $code = ($convert > 0)? strtoupper($code) : strtolower($code);
    }
    return $code;
}

//隐藏中间字符
function maskString($str,$startLength, $length=1, $sl = '*') 
{
    $startStr = mb_substr($str, 0, $startLength);
    $endStr = mb_substr($str, $startLength + $length);
    $maskStr = '';
    for ($i = 0; $i < $length; $i++) {
        $maskStr .= $sl;
    }
    return $startStr.$maskStr.$endStr;
}

/*
 * 生成交易流水号
 * @param char(2) $type
 */
function doOrderSn($type){
	return date('YmdHis') .$type. substr(microtime(), 2, 3) .  sprintf('%02d', rand(0, 99));
}


//后台sql输入框语句过滤
function sql_replace($str){
	$farr = ["/insert[\s]+|update[\s]+|create[\s]+|alter[\s]+|delete[\s]+|drop[\s]+|load_file|outfile|dump/is"];
	$str = preg_replace($farr,'',$str);
	return $str;
}

//上传文件黑名单过滤
function upload_replace($str){
	$farr = ["/php|php3|php4|php5|phtml|pht|/is"];
	$str = preg_replace($farr,'',$str);
	return $str;
}

//查询方法过滤
function serach_in($str){
	$farr = ["/^select[\s]+|insert[\s]+|and[\s]+|or[\s]+|create[\s]+|update[\s]+|delete[\s]+|alter[\s]+|count[\s]+|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/i"];
	$str = preg_replace($farr,'',$str);
	return trim($str);
}

//获取键值对信息
function getItemData($data){
	if(count($data) > 0){
		foreach($data as $key=>$v){
			if(count($v) == 0){
				unset($data[$key]);
			}
		}
		$str = json_encode(array_values($data),JSON_UNESCAPED_UNICODE);
	}else{
		$str = '';
	}
	return $str;
}


/**
 * tp官方数组查询方法废弃，数组转化为现有支持的查询方法
 * @param array $data 原始查询条件
 * @return array
 */
function formatWhere($data){
	$where = [];
	foreach( $data as $k=>$v){
		if(is_array($v)){
			if(((string) $v[1] <> null && !is_array($v[1])) || (is_array($v[1]) && (string) $v[1][0] <> null)){
				switch(strtolower($v[0])){
					//模糊查询
					case 'like':
						$v[1] = '%'.$v[1].'%';
					break;

					//表达式查询
					case 'exp':
						$v[1] = Db::raw($v[1]);
					break;
				}
				$where[] = [$k,$v[0],$v[1]];
			}
		}else{
			if((string) $v != null){
				$where[] = [$k,'=',$v];
			}
		}
	}
	return $where;
}


/**
 * 生成sql查询语句
 * @access protected
 * @param  sql     原始sql语句
 * @param  $where  查询条件
 * @param  $limit  分页
 * @param  $orderby  排序
 * @return array
 */
function loadList($sql,$where=[],$limit,$orderby){
	$sql = str_replace('pre_',config('database.connections.mysql.prefix'),strtolower($sql));
	foreach($where as $key=>$val){
		if(is_array($val)){
			switch($val[1]){
				case 'between':
					if(empty($val[2][0]) && !empty($val[2][1])){
						$map .= $val[0].' < '.$val[2][1].' and ';
					}
					if(!empty($val[2][0]) && empty($val[2][1])){
						$map .= $val[0].' > '.$val[2][1].' and ';
					}
					if(!empty($val[2][0]) && !empty($val[2][1])){
						$map .= $val[0].' between '.$val[2][0].' and '.$val[2][1].' and ';
					}
				break;

				case 'exp':
					$map .= $val[0].' '.$val[2].' and ';
				break;

				case 'in':
					$map .= $val[0].' in ('.$val[2].') and ';
				break;

				case 'not in':
					$map .= $val[0].' not in ('.$val[2].') and ';
				break;

				case 'find in set':
					$map .= ' find_in_set(\''.$val[2].'\','.$val[0].') and ';
				break;

				default:
					$map .= $val[0].' '.$val[1]." '".$val[2]."'".' and ';
				break;
			}
		}
	}
	$map .= '1=1';

	$is_where = strripos($sql,"where");
	if($is_where === false){
		$where = !empty($where) ?  ' where '.$map : '';
		$sql = $sql.$where;
	}else{
		$l_sql = substr($sql, 0, $is_where);
		$r_sql = substr($sql, $is_where+5, strlen($sql)- $is_where - 5);
		$where = !empty($where) ?  ' where '.$map.' and ' : ' where ';
		$sql = $l_sql . $where . $r_sql;
	}

	$group = preg_split('/group\s+by/',$sql);
	if(is_array($group)){
		$is_where = strripos($group[1],"where");
		if($is_where){
			$l_sql = substr($group[1], 0, $is_where);
			$r_sql = substr($group[1], $is_where+5, strlen($group[1])- $is_where - 5);
			$where = !empty($is_where) ? 'where' : '';
			$sql = $group[0] . $where.$r_sql.' group by '.$l_sql;
		}
	}
	$limit = ' limit '.$limit;

	$countWhere = 'select count(*) as count from ('.$sql.') as tp';

	if (strripos($sql,"order by")=== false && $orderby) {
		$sql .= ' order by '.$orderby;
	}

	if (strripos($sql,"limit")=== false) {
		$sql .= $limit;
	}

	$result = Db::query($sql);
	$count = Db::query($countWhere);

	return ['data'=>$result,'total'=>$count[0]['count']];
}

//过滤xss
function remove_xss($string) {
    $string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $string);
    $parm1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound');
    $parm2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
    $parm = array_merge($parm1, $parm2);
    for ($i = 0; $i < sizeof($parm); $i++) {
        $pattern = '/';
        for ($j = 0; $j < strlen($parm[$i]); $j++) {
            if ($j > 0) {
                $pattern .= '(';
                $pattern .= '(&#[x|X]0([9][a][b]);?)?';
                $pattern .= '|(&#0([9][10][13]);?)?';
                $pattern .= ')?';
            }
            $pattern .= $parm[$i][$j];
        }
        $pattern .= '/i';
        $string = preg_replace($pattern, '', $string);
    }
    return $string;
}

/**
 * 实例化数据库类
 * @param string        $name 操作的数据表名称（不含前缀）
 * @param array|string  $config 数据库配置参数
 * @param bool          $force 是否强制重新连接
 * @return \think\db\Query
 */
if (!function_exists('db')) {

    function db($name = '',$connect='')
    {
		if(empty($connect)){
			$connect = config('database.default');
		}
        return Db::connect($connect,false)->name($name);
    }
}
function msg($code, $msg="", $data='', $count=0){
    return json(["code"=>$code,"msg"=>$msg,"data"=>$data,"count"=>$count]);
}
function commentType(){
    $data=Db::name('types')->where('type','=','comment')->field('id,name')->select();

   return $data;
}
function createCode($user_id) {

    static $source_string = 'J2RSTUV67MWX89KLYZE5FCDG3HQA4B1NOPI';

    $num = $user_id+9999;

    $code = '';

    while ( $num > 0) {

        $mod = $num % 35;

        $num = ($num - $mod) / 35;

        $code = $source_string[$mod].$code;

    }
    if(empty($code[3]))

        $code = str_pad($code,4,'0',STR_PAD_LEFT);

    return $code;

}

function decode($code) {

    static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';

    if (strrpos($code, '0') !== false)

        $code = substr($code, strrpos($code, '0')+1);

    $len = strlen($code);

    $code = strrev($code);

    $num = 0;

    for ($i=0; $i < $len; $i++) {

        $num += strpos($source_string, $code[$i]) * pow(35, $i);

    }

    return $num-9999;

}

function getUserToken(){
    $token = trim(Request::header('token', ''),'"');
    return $token;
}
function getUserId(){
    $token = trim(Request::header('token', ''),'"');
    return Cache::get('user_token'.$token);
}
function getTechnicianId(){
    $token = trim(Request::header('token', ''),'"');
    return Cache::get('technician_token'.$token);
}

function opinionType(){
    $data=Db::name('types')->where('type','=','opinion')->field('id,name')->select();
    return $data;
}
function cancelType(){
    $data=Db::name('types')->where('type','=','cancel')->field('id,name')->select();
    return $data;
}

function order_sn($type){
    //$order_sn=$type.date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    $order_sn = $type.substr(date('YmdHis'), 2, 12).uniqid().rand(1000, 9999);
    return $order_sn;
}
//小时转数字下标
function hourToIndex($t){
    $hour=intval(date('H',$t))*2;
    $min=intval(date('i',$t))>29?1:0;
    return $hour+$min;
}
function indexToHour($index){
    $hour=$index%2;
    if($hour==1){
        $index-=1;
       $min=":30";
    }else{
        $min=":00";
    }
    if($index>19){
        $hour=strval($index/2);
    }else{
        $hour='0'.strval($index/2);
    }

    return $hour.$min;
}
//上传证书
function uploadCert($file){

    if($file['type']!='application/x-x509-ca-cert'){
        return msg('0','非法文件格式');
    }
    if ($_FILES["file"]["error"] > 0)
    {
        return ['code'=>0,'msg'=>$file["error"]];
    }
    else
    {
        move_uploaded_file($file["tmp_name"], root_path('public\uploads\wx')  .$file["name"]);
        return ['code'=>0,'msg'=>'上传成功'];
    }
}



function createNews($uid,$content,$user_type,$type,$technician_id=0){
    $data=[
        'user_id'=>$uid,
        'content'=>$content,
        'user_type'=>$user_type,
        'type'=>$type,
        'technician_id'=>$technician_id,
        'create_time'=>time()
    ];
    Db::name('news')->insert($data);
}

function getAccessToken(){
    $access_token = cache('bdt_access_token');
    if(!$access_token){
        $config=json_decode(Db::name('base_config')->where('name','wx_config')->value('data'),true);
        $url='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$config['wx_app_id'].'&secret='.$config['wx_app_secret'];
        $res=json_decode(httpPost($url,''),true);
        Cache::set('bdt_access_token', $res['access_token'],7100);
        return $res['access_token'];
    }
    return $access_token;
}

function httpPost($url, $data) { // 模拟提交数据函数
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
    curl_setopt($curl, CURLOPT_USERAGENT, !empty($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:''); // 模拟用户使用的浏览器
    curl_setopt($curl, CURLOPT_POST, true); // 发送一个常规的Post请求
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); // Post提交的数据包
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
    curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charset=utf-8'
    )); //类型为json
    $result = curl_exec($curl); // 执行操作
    curl_close($curl); // 关键CURL会话
    return $result; // 返回数据
}
function httpGet($url)
{
//    $request_headers[]  = 'Authorization: '.$token;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
//    curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    $output = curl_exec($ch);
    curl_close($ch);

    return $output;
}

/**
 * 发送提现审核通知
 * @param $tech_id  技师id
 * @param $money  金额
 * @param $status  审核通过；审核拒绝
 * @param $create_time  申请时间
 */
function sendWithdrawalMsg($tech_id,$money,$status,$create_time){
    $openid=Db::name('technician')->where('id',$tech_id)->value('openid');
    $config=json_decode(Db::name('base_config')->where('name','wx_config')->value('data'),true);
    $access_token =getAccessToken();
    $url='https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token='.$access_token;
    $data=[
        'touser'=>$openid,
        'mp_template_msg'=>[
            'appid'=>'wxdb5f2028eae7f644',
            'template_id'=>'pE0sWTKZhHHQU78yzkj2-nbu5BvJoOaScFqEFsWaR9A',
            'url'=>'',
            'miniprogram'=>[
                'appid'=>$config['wx_app_id'],
                'path'=>'page/page/index'
            ],
            'data'=>[
                'first'=>[
                    'value'=>'提现审核通知',
                    'color'=>'#173177'
                ],
                'keyword1'=>[
                    'value'=>$money,
                    'color'=>'#173177'
                ],
                'keyword2'=>[
                    'value'=>'支付宝提现',
                    'color'=>'#173177'
                ],
                'keyword3'=>[
                    'value'=>date('Y-m-d H-i',$create_time),
                    'color'=>'#173177'
                ],
                'keyword4'=>[
                    'value'=>$status,
                    'color'=>'#173177'
                ],
                'keyword5'=>[
                    'value'=>date('Y-m-d H-i'),
                    'color'=>'#173177'
                ],
                'remark'=>[
                    'value'=>'',
                    'color'=>'#173177'
                ],
            ]
        ],

    ];
    $res=json_decode(httpPost($url,$data),true);
    return $res;
}

/**
 * 发送认证审核通知
 * @param $tech_id  技师id
 * @param $project  头像；身份；资质；基本资料
 * @param $status  审核通过；审核拒绝
 */
function sendAuthenticationMsg($tech_id, $project,$status){
    $tech=Db::name('technician')->where('id',$tech_id)->field('openid,nickname')->find();
    $config=json_decode(Db::name('base_config')->where('name','wx_config')->value('data'),true);
    $access_token =getAccessToken();
    $url='https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token='.$access_token;
    $data=[
        'touser'=>$tech['openid'],
        'mp_template_msg'=>[
            'appid'=>'wxdb5f2028eae7f644',
            'template_id'=>'-Z17hvT-mRmNCSdyDLNWTiBk6O9ZZKxLycZ6gsZjKf0',
            'url'=>'',
            'miniprogram'=>[
                'appid'=>$config['wx_app_id'],
                'path'=>'page/page/index'
            ],
            'data'=>[
                'first'=>[
                    'value'=>$project.'认证审核通知',
                    'color'=>'#173177'
                ],
                'keyword1'=>[
                    'value'=>$tech['nickname'],
                    'color'=>'#173177'
                ],
                'keyword2'=>[
                  'value'=>$status,
                  'color'=>'#173177'
              ],
                'keyword3'=>[
                    'value'=>date("Y-m-d H:i:s",time()),
                    'color'=>'#173177'
                ],
                'remark'=>[
                    'value'=>'',
                    'color'=>'#173177'
                ],
            ]
        ],

    ];
    $res=json_decode(httpPost($url,$data),true);
    return $res;
}

/**
 * 发送订单状态通知
 * @param $tech_id  技师id
 * @param $service  服务名称
 * @param $status  下单；新订单；取消订单
 * @param $order_sn  订单号
 * @param $appointment_time  服务时间
 */
function sendOrderMsg($tech_id, $service,$status,$order_sn,$appointment_time){
    $tech=Db::name('technician')->where('id',$tech_id)->field('openid,nickname')->find();
    $config=json_decode(Db::name('base_config')->where('name','wx_config')->value('data'),true);
    $access_token =getAccessToken();
    $url='https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token='.$access_token;
    $url ='https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token='.$access_token;
    $data=[
        'touser'          => $tech['openid'],
        'mp_template_msg' => [
            'appid'       => 'wx8faf55e130f9919f',
            // 'template_id' => 'ahph7Lo_Ngj3xLzRUhQ_2Hycc2wrHnCZcj0iXQ1ipHo',
            // 'template_id' => 'z9IpFfGmUGoPceSdASlP2zDn_LAaVjfXstKiom7dUuA',
            'template_id' => 'FFO8JKzmlYTQTwPO-C3dtOjsiATYaD_kKG2-Y8DSjGY',
            'url'         => 'page/page/index',
            'miniprogram' => [
                'appid' => 'wxe950d42771d25da2',
                'path'  => 'page/page/index'
            ],
            'data'        => [
                'first'    => [
                    'value' => '订单通知',
                    'color' => '#173177'
                ],
                'keyword1' => [
                    'value' => $service,
                    'color' => '#173177'
                ],
                'keyword2' => [
                    'value' => $order_sn,
                    'color' => '#173177'
                ],
                'keyword3' => [
                    'value' => $status,
                    'color' => '#173177'
                ],
                'keyword4' => [
                    'value' => date('Y-m-d H:i', $appointment_time),
                    'color' => '#173177'
                ],
                'remark'   => [
                    'value' => '',
                    'color' => '#173177'
                ],
            ]
        ],

    ];
    // $res = json_decode(httpPost($url, $data), true);
    $res = json_decode(httpGet($url), true);
    //dd($url,$res,$data);
    return $res;
}

/**
 * 发送关注状态通知
 * @param $tech_id  技师id
 */
function sendFollowMsg($tech_id){
    $tech=Db::name('technician')->where('id',$tech_id)->field('openid,nickname')->find();
    $config=json_decode(Db::name('base_config')->where('name','wx_config')->value('data'),true);
    $customer_service=json_decode(Db::name('base_config')->where('name','customer_service')->value('data'),true);
    $access_token =getAccessToken();
    $url='https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token='.$access_token;
    $data=[
        'touser'=>$tech['openid'],
        'mp_template_msg'=>[
            'appid'=>'wxdb5f2028eae7f644',
            'template_id'=>'jcNH9cL7rfdjxroOsLq0aLUBmJzCwBhWO5BzwSNNVxE',
            'url'=>'',
            'miniprogram'=>[
                'appid'=>$config['wx_app_id'],
                'path'=>'page/page/index'
            ],
            'data'=>[
                'first'=>[
                    'value'=>'关注公众号通知',
                    'color'=>'#173177'
                ],
                'keyword1'=>[
                    'value'=>'通过公众号消息通知',
                    'color'=>'#173177'
                ],
                'keyword2'=>[
                    'value'=>$customer_service['mobile'],
                    'color'=>'#173177'
                ],
                'remark'=>[
                    'value'=>'',
                    'color'=>'#173177'
                ],
            ]
        ],

    ];
    // $res=json_decode(httpPost($url,$data),true);
    $res=json_decode(httpGet($url),true);
    return $res;
}

if (!function_exists('dingMarkdown')) {
    /**
     * 发送 markdown 定制化钉钉消息
     * todo 以下代码格式为定制化，切勿随意改动格式
     * 使用该方法必须先安装  composer require wangju/ding-notice 扩展包
     * 由于消息发送太频繁会严重影响群成员的使用体验，因此钉钉开放平台对自定义机器人发送消息的频率作出以下限制：
     * 每个机器人每分钟最多发送20条消息到群里，如果超过20条，会限流10分钟。
     * @User zhanglangeba
     * @param       $title
     * @param array $content
     * @return mixed
     */
    function dingMarkdown(string $title, $content, $config = 'default')
    {
        $ding = new \DingNotice\DingTalk([
            "default" => [
                'enabled' => true,
                'token' => "2d94ad74ba537cc4b144ff390ab7280799199ec940e318d057ee6c388d9fe227",
                'timeout' => 2.0,
                'ssl_verify' => true,
                'secret' => 'SEC271517c593f3a8f79f0f301844fea0f381443104d52585eb2d02f1ae25d0f0de',
            ]
        ]);
        $text = '## ' . $title . '
>';
        // 字符串转数组
        if (!is_array($content)) {
            $content = compact('content');
        }

        foreach ($content as $k => $v) {
            $text .= '**' . $k . '**' . ':' . json_encode($v, JSON_UNESCAPED_UNICODE) . '\
';
        }
        return $ding->markdown($title, $text);
    }
}

/**
 * 获取客户端 IP
 * @User zhanglangeba
 * @return string
 */
function getClientIp(): string
{
    if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
        $onlineip = getenv('HTTP_CLIENT_IP');
    } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
        $onlineip = getenv('HTTP_X_FORWARDED_FOR');
    } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
        $onlineip = getenv('REMOTE_ADDR');
    } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
        $onlineip = $_SERVER['REMOTE_ADDR'];
    } else {
        $onlineip = '127.0.0.1';
    }
    preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipmatches);
    $ip = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';

    return $ip;
}

/**
 * 公共请求
 * @User yaokai
 * @param string $method
 * @param string $uri
 * @param array  $options
 * @param int    $timeout
 * @return mixed
 * @throws \GuzzleHttp\Exception\GuzzleException
 */
function commonGuzzle(string $method, $uri = '', array $options = [], $timeout = 60)
{
    $client = new \GuzzleHttp\Client(['timeout' => $timeout]);

    $respond = $client->request($method, $uri, $options);

    $data = json_decode($respond->getBody()->getContents(), true);

    return $data;
}